#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <memory>
#include <functional>
#include "Common.hpp"
#include "Connection.hpp"
#include "Log.hpp"
#include "INETADDR.hpp"
#define SIZE 1024
class Channel : public Connection
{
public:
    Channel(int sockfd, INETADDR &client)
        : _sockfd(sockfd), _client(client)
    {
        SetNoBlock(_sockfd);
    }
    void Recver() override
    {
        char buffer[1024];
        while (true) // ET模式需要循环读取
        {
            ssize_t n = recv(_sockfd, buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                _inbuffer += buffer;

                // 处理接收到的数据
                if (_handler != nullptr)
                {
                    string response = _handler(_inbuffer);
                    if (!response.empty())
                    {
                        _outbuffer += response;
                        // 注册写事件
                        GetOwner()->EnableReadWrite(_sockfd, true, true);
                    }
                }
            }
            else if (n == 0) // 客户端关闭连接
            {
                GetOwner()->DelConnection(_sockfd);
                break;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                    break; // 非阻塞模式下无数据可读

                LOG(LogLevel::ERROR) << "recv error: " << strerror(errno);
                GetOwner()->DelConnection(_sockfd);
                break;
            }
        }
    }
    void Sender() override
    {
        while (true)
        {
            ssize_t n = send(_sockfd, _outbuffer.c_str(), _outbuffer.size(), 0);
            if (n > 0)
            {
                _outbuffer.erase(0, n);
                if (_outbuffer.empty())
                    break;
            }
            else if (n == 0)
            {
                break;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                    break;
                if (errno == EINTR)
                    continue;
                else
                {
                    Excepter();
                    return;
                }
            }
        }

        // 1. 数据发送完毕
        // 2. 发送条件不具备
        if (!_outbuffer.empty())
        {
            // 开启对写事件的关心
            GetOwner()->EnableReadWrite(_sockfd, true, true);
        }
        else
        {
            GetOwner()->EnableReadWrite(_sockfd, true, false);
        }
    }
    void Excepter() override
    {
        // 所有的异常，都被我归一到了这个函数内部！！
        GetOwner()->DelConnection(_sockfd);
    }
    int GetFd() override
    {
        return _sockfd;
    }
    string &Inbuffer()
    {
        return _inbuffer;
    }
    void AppendOutBuffer(const string &out)
    {
        _outbuffer += out;
    }
    ~Channel()
    {
        close(_sockfd);
    }

private:
    int _sockfd;
    string _inbuffer;
    string _outbuffer;
    INETADDR _client;
};